home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / textf.arc / TEXTF.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-28  |  8KB  |  244 lines

  1. {$R-,V-,I-,S-}
  2. Unit textf;
  3.  
  4. { -USES Nothing- }
  5.  
  6. (*********************************************************************
  7.                    Fast disk file text reading operations.
  8.  
  9.  This program is a OOP'd version of Don Strenczewilk's [72617,132]
  10.  RLINE package.
  11.  
  12.  Modifications by Arthur Zatarain, C'serve 73417,525  09/25/89
  13.  
  14.  
  15. This unit contains some fast reading routines designed to work with
  16. standard ASCII disk files:
  17.  
  18. FOpen             Open a file
  19. FRead             Read the next character
  20. FReadLn           Read the next string
  21. FFilePos          Return the current position in the file
  22. FSeek             Seek to any position
  23. FClose            Close a file
  24.  
  25. The RLINE unit uses about 600 bytes of your programs code space,
  26. and 0 data.
  27.  
  28. **********************************************************************)
  29. Interface
  30. (*********************************************************************)
  31.  
  32. (*
  33.   An object of type RFrec is maintained by the TEXTF Unit and
  34.   contains information about the file handle, the buffer address, current
  35.   position in the file, size of the buffer, and current location in buffer:
  36. *)
  37.  
  38. TYPE
  39.   { Generic type which allows access to segment and offset of pointer }
  40. SegOfsPtr = RECORD
  41.   CASE Boolean OF
  42.     True : (Pntr : Pointer);
  43.     False : (Ofst, Sgmnt : Word);
  44. END;
  45.  
  46. RFrec = object
  47.   Handle  : Word;        { File handle }
  48.   BufPtr  : SegOfsPtr;   { BufOfs, BufSeg}
  49.   Bpo,                   { Current buffer position }
  50.   BSize,                 { Buffer size in bytes }
  51.   BLeft,                 { Bytes left in buffer to scan }
  52.   NBufs   : Word;        { Number of buffers read. = 0 if none. }
  53.   TotBytesInBuf : Word;  { Total bytes that were read into current buffer.}
  54.   constructor init;
  55.   PROCEDURE FClose;     virtual;
  56.   FUNCTION   FSeek(FPo : LongInt) : Word;  virtual;
  57.   function   FOpen(Fn      : STRING;  { Name of file to open. }
  58.                    DBSize  : Word;    { Size of buffer. 512 bytes minimum. }
  59.                    VAR BufP)          { Disk buffer to use. }
  60.                            : Word;   virtual;
  61. { String variable to read next line to. }
  62.   FUNCTION FReadLn(VAR S   : STRING) : word;  virtual;
  63.   FUNCTION FRead(VAR Ch    : Char)  { String variable to read next line to. }
  64.                            : Word;    virtual;
  65.   FUNCTION FFilePos : LongInt;    virtual;
  66.  
  67. END;  { rfrec object }
  68.  
  69. (*
  70. All you need to know to use the RLINE routines is that you must declare a
  71. variable of type RFrec somewhere.
  72.  
  73. Function FOpen
  74.  
  75.       function FOpen(Fn : STRING;  { Name of file to open. }
  76.                DBSize   : Word;    { Size of buffer. 512 bytes minimum. }
  77.                VAR BufP)          { Disk buffer to use. }
  78.                : Word;
  79.  
  80.  
  81. A file must first be successfully opened with a call to FOpen, before any of
  82. the other routines are used.
  83.  
  84. A buffer must be declared to be passed to the FOpen function.  There are no
  85. restrictions on the location of the buffer, so it can be a global or local
  86. variable, or allocated with New() or GetMem().
  87.  
  88.  
  89.   If successful:
  90.     Returns 0.
  91.  
  92.   If failed:
  93.     Returns DOS error code if a DOS error occured,
  94.     or error 12 (Invalid File Access Code) if the buffer size is 0.
  95.  
  96. TRAPS:
  97. If using a buffer allocated with New() or GetMem(), be sure to use the caret
  98. after it for the BufP parameter. Ie. IF FOpen(RF, Fn, BSize, BufP^)...
  99.  
  100. Never call FOpen twice with the same RFrec variable without closing the old
  101. one first.
  102.  
  103. EXAMPLE:
  104. VAR
  105.   RF : RFrec;
  106.   Buffer : Array[1..2048] of Char;
  107.   Error : Word;
  108. BEGIN
  109.   Error := FOpen(RF, 'HELLO.PAS', Sizeof(Buffer), Buffer);
  110.   If Error = 0
  111.   THEN Writeln('Success')
  112.   ELSE Writeln('Error: ', i);
  113. ...
  114.  
  115. --------------------------------------------------------------------------
  116. Procedure FClose  - When done with the file, it must be closed with a call to
  117. FClose:
  118.  
  119. PROCEDURE FClose(VAR RF : RFrec);
  120.  
  121. Closes previously opened RFrec.
  122. Returns nothing.
  123.  
  124. This procedure attempts to identify whether the file has been previously
  125. opened before it attempts to ask DOS to close it.  It does not attempt to
  126. close the file if:
  127.  a) RF.BSize = 0. Function FOpen sets RF.BSize to 0 if DOS open failed.
  128. or
  129.  b) RF.Handle < 5, in which case it would be a standard DOS handle, which
  130. shouln't be closed.
  131.  
  132. TRAP: A problem that could occur with this scheme would be if (the file was
  133. never even attempted to be opened by FOpen) AND (the handle = the handle of
  134. a file that is currently opened somewhere else in the program).
  135.  
  136. ----------------------------------------------------------------------
  137. Function FReadLn
  138.  
  139. FReadLn - Reads a string of characters up to the next ^M, or ^Z <EOF>, or
  140. the physical end of file, whichever comes first.
  141.  
  142. The maximum length of the string returned to caller is 255 characters.  If
  143. more than 255 characters are passed in the file before ^M or <EOF>, the
  144. remaining characters are irretreivable.
  145.  
  146. FUNCTION FReadLn(VAR RF  : RFrec;  { Previously opened RFrec variable }
  147.                  VAR S   : STRING) { String variable to read next line to. }
  148.                  : Word;
  149.  
  150. On success:
  151.   Returns 0.
  152.   S = next string read from file RF.Handle.
  153. On failure:
  154.   returns either DOS error code,
  155.   or $FFFF if End of File
  156.  
  157. Works like a Turbo Readln(F, S); except:
  158.     (1) It works only with disk files.
  159.     (2) Only reads strings. ie. not integers, words, or any other type.
  160.     (3) It is much faster.
  161.     (4) Doesn't stop when a ^Z is encountered before end of file.  If a ^Z
  162. is encountered AT the end of file, it is stripped.  Any ^Z's encountered
  163. before the physical end of the file are passed on to the string.
  164.  
  165. ----------------------------------------------------------------------
  166. Function FRead - Reads the next character from the file:
  167. }
  168. FUNCTION FRead(VAR RF  : RFrec; { Previously opened RFrec variable }
  169.                VAR Ch  : Char)  { String variable to read next line to. }
  170.                : Word;
  171. {
  172. Works the same as FReadLn but returns one character instead of a string.
  173. All characters are passed on to Ch except if a ^Z is at end of file.
  174.  
  175. If successful:
  176.  Returns 0.  Ch = next character in the file.
  177.  
  178. If failed:
  179.  Returns either DOS error code,
  180.  or $FFFF if End of File
  181.  
  182. ----------------------------------------------------------------------
  183. Function FFilePos - Returns current file position for use with FSeek.
  184.  
  185. FUNCTION FFilePos : LongInt;
  186.  
  187. Returns current file position. RF must have been previously opened.
  188. If FFilePos is called before FOpen is called successfully, the results will
  189. be meaningless.
  190.  
  191. ----------------------------------------------------------------------
  192. Function FSeek - Seeks to position FPo in previously opened RF.
  193.  
  194. FUNCTION FSeek(FPo : LongInt) : Word;
  195.  
  196. If successful, Returns 0
  197. If failed, returns DOS error code.
  198.  
  199. To Reset the file, call RFSeek with FPo := 0.  Ie. FSeek(RF,0);
  200.  
  201. On a normal ^M^J ascii file, FFilePos will most often return the position of
  202. the ^J after a call to FReadLn.  Because FReadLn strips leading ^J's, this
  203. shouldn't be a problem.  But, bear that in mind if using the FFilePos
  204. results for your own untyped file routines.
  205. *)
  206.  
  207. (****************************************************************************)
  208. Implementation
  209. (****************************************************************************)
  210.  
  211.   {=================================================================}
  212.   {$L textf.OBJ}            { EXTERNAL DECLARATIONS }
  213.   { All PROCs are FAR }
  214.  
  215.   FUNCTION rfrec.FOpen(Fn      : STRING;
  216.                        DBSize  : Word;
  217.                        VAR BufP) : Word; EXTERNAL;
  218.  
  219.   FUNCTION rfrec.FReadLn(VAR S  : STRING) : Word; EXTERNAL;
  220.  
  221.   FUNCTION rfrec.FRead(VAR Ch  : Char) : Word; EXTERNAL;
  222.  
  223.   FUNCTION rfrec.FSeek(FPo : LongInt) : Word; EXTERNAL;
  224.  
  225.   PROCEDURE rfrec.FClose; EXTERNAL;
  226.  
  227.   {=================================================================}
  228.  
  229. FUNCTION rfrec.FFilePos : LongInt;
  230.   BEGIN
  231.     { RF.NBufs is equal to 1 when there has been at least 1 buffer read. }
  232.     IF NBufs = 0  { If current buffer number = 0, nothing's been read. }
  233.     THEN FFilePos := 0
  234.     ELSE FFilePos := (LongInt(NBufs-1)*BSize)+(Bpo-BufPtr.Ofst);
  235.  
  236. END;
  237.  
  238. constructor rfrec.init;
  239. begin
  240. end;
  241.  
  242. end.
  243.  
  244.